package com.cema.manage.project.manage.adRecord.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cema.manage.common.utils.DateUtils;
import com.cema.manage.framework.web.controller.BaseController;
import com.cema.manage.framework.web.page.TableDataInfo;
import com.cema.manage.project.manage.adRecord.domain.AdRecord;
import com.cema.manage.project.manage.adRecord.domain.AdRecordHourVo;
import com.cema.manage.project.manage.adRecord.domain.AdRecordVo;
import com.cema.manage.project.manage.adRecord.domain.RankListVo;
import com.cema.manage.project.manage.adRecord.service.IAdRecordService;
import com.cema.manage.project.manage.friend.service.IFriendService;
import com.google.gson.Gson;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;


/**
 * 广告记录 信息操作处理
 *
 * @author reasahi
 * @date 2024-07-26
 */
@Controller
@RequestMapping("/manage/adRecord")
public class AdRecordController extends BaseController {
    private String prefix = "manage/adRecord";

    @Autowired
    private IAdRecordService adRecordService;

    @Resource
    private IFriendService iFriendService;

    @GetMapping()
    @RequiresPermissions("manage:adRecord:view")
    public String adRecord() {
        return prefix + "/adRecord";
    }

    @GetMapping("/hour")
    @RequiresPermissions("manage:adRecord:view:hour")
    public String adRecordHour(Model model) {
        AdRecordHourVo adRecordHourVo = new AdRecordHourVo();
        adRecordHourVo.setCreateTime(DateUtil.format(new Date(), DateUtils.YYYY_MM_DD));
        Map<String, Object> map = adRecordService.getHour(adRecordHourVo);
        Gson gson = new Gson();
        model.addAttribute("hourModel", gson.toJson(map));
        return prefix + "/adRecordHour";
    }

    /**
     * 查询广告记录列表
     */
    @RequiresPermissions("manage:adRecord:list:hour")
    @ResponseBody
    @RequestMapping("/list_hour")
    public JSONObject queryListHour(AdRecordHourVo adRecordHourVo) {
        Map<String, Object> map = adRecordService.getHour(adRecordHourVo);
        return new JSONObject(map);
    }

    @GetMapping("/rankList/{id}")
    @RequiresPermissions("manage:adRecordRankList:view")
    public String adRecordRankListId(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("index", id);
        return prefix + "/adRecordRankList";
    }

    @GetMapping("/parentId/{parentId}")
    @RequiresPermissions("manage:adRecordRankList:view")
    public String adRecordRankList(@PathVariable("parentId") String parentId, Model model) {
        String[] strings = parentId.split(StrUtil.COMMA);
        model.addAttribute("parentId", strings[0]);
        model.addAttribute("index", strings[1]);
        return prefix + "/adRecordRankListParent";
    }


    @GetMapping("{id}")
    @RequiresPermissions("manage:adRecord:view")
    public String adRecord(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("usId", id);
        return prefix + "/adRecord";
    }

    /**
     * 查询广告记录列表
     */
    @RequiresPermissions("manage:adRecord:list")
    @ResponseBody
    @PostMapping("/rankList")
    public TableDataInfo queryRankList(AdRecordVo adRecordVo) {
        List<RankListVo> recordList = adRecordService.getRankList(adRecordVo);
        return getDataTable(recordList);
    }

    @RequiresPermissions("manage:adRecord:excel")
    @GetMapping("/excel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse resp) {
        AdRecordVo adRecordVo = new AdRecordVo();
        adRecordVo.setArChannel(request.getParameter("arChannel"));
        String startTime = request.getParameter("startTime");
        adRecordVo.setUsParentId(request.getParameter("usParentId"));
        adRecordVo.setIndex(Integer.parseInt(request.getParameter("index")));
        adRecordVo.setUvChannel(Integer.parseInt(request.getParameter("index")));
        if (StrUtil.isNotEmpty(startTime)) {
            adRecordVo.setStartTime(DateUtil.parse(startTime, DateUtils.YYYY_MM_DD_HH_MM_SS));
        }
        String endTime = request.getParameter("endTime");
        if (StrUtil.isNotEmpty(endTime)) {
            adRecordVo.setEndTime(DateUtil.parse(endTime, DateUtils.YYYY_MM_DD_HH_MM_SS));
        }
        ExcelWriter writer = null;
        ServletOutputStream outputStream = null;
        try {
            // 省略数据获取的操作....
            writer = ExcelUtil.getWriter(true);
            // 设置表格列
            writer.writeRow(Arrays.asList("排行", "用户ID", "广告次数", "广告金币", "副广次数", "副广金币", "渠道ID"));

            // 数据需要循环写入....
            // 写入数据操作
            List<RankListVo> recordList = adRecordService.getRankList(adRecordVo);
            for (RankListVo rankListVo : recordList) {
                writer.writeRow(Arrays.asList(rankListVo.getIndex(), rankListVo.getId(), rankListVo.getCount(), rankListVo.getMoney(), rankListVo.getSecondaryCount(), rankListVo.getSecondaryMoney(), rankListVo.getParenId()));
            }
            // 设置响应头content-type
            resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset:utf-8");
            // 设置下载文件名
            String fileName = URLEncoder.encode("排行榜", "UTF-8");
            resp.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            outputStream = resp.getOutputStream();
            writer.flush(outputStream, true);
            writer.close();
            outputStream.close();
        } catch (IOException throwables) {
            throwables.printStackTrace();
        }
    }

    /**
     * 查询广告记录列表
     */
    @RequiresPermissions("manage:adRecord:list")
    @ResponseBody
    @RequestMapping("/list")
    public TableDataInfo queryList(AdRecordVo adRecordVo) {
        EntityWrapper<AdRecord> entityWrapper = getEntityWrapper(adRecordVo);
        startPage();
        List<AdRecord> recordList = adRecordService.selectList(entityWrapper);
        return getDataTable(recordList);
    }

    /**
     * 查询广告记录列表
     */
    @RequiresPermissions("manage:adRecord:list")
    @ResponseBody
    @RequestMapping("/statistics")
    public JSONObject list(AdRecordVo adRecordVo) {
        EntityWrapper<AdRecord> entityWrapper = getEntityWrapper(adRecordVo);
        List<AdRecord> adRecordList = adRecordService.selectList(entityWrapper);
        Map<String, Long> map = new HashMap<>(2);
        long usMoneySum = 0L;
        long arRealityMoneySum = 0L;
        long usParentMoneySum = 0L;
        if (ObjectUtil.isNotNull(adRecordList)) {
            usMoneySum = adRecordList.stream().mapToInt(AdRecord::getUsMoney).sum();
            arRealityMoneySum = adRecordList.stream().mapToInt(AdRecord::getArRealityMoney).sum();
            usParentMoneySum = adRecordList.stream().filter(adRecord -> ObjectUtil.isNotNull(adRecord.getUsParentMoney())).mapToInt(AdRecord::getUsParentMoney).sum();
        }
        map.put("usMoneySum", usMoneySum);
        map.put("usParentMoneySum", usParentMoneySum);
        map.put("arRealityMoneySum", arRealityMoneySum);
        return new JSONObject(map);
    }

    @NotNull
    private EntityWrapper<AdRecord> getEntityWrapper(AdRecordVo adRecordVo) {
        EntityWrapper<AdRecord> entityWrapper = new EntityWrapper<>();
        Date start = adRecordVo.getStartTime();
        if (ObjectUtil.isNotNull(start)) {
            entityWrapper.andNew();
            entityWrapper.between("create_time", start, adRecordVo.getEndTime());
        }
        String arChannel = adRecordVo.getArChannel();
        if (StrUtil.isNotEmpty(arChannel)) {
            entityWrapper.eq("ar_channel", arChannel);
        }
        Integer uvChannel = adRecordVo.getUvChannel();
        if (ObjectUtil.isNotEmpty(uvChannel)) {
            entityWrapper.eq("uv_channel", uvChannel);
        }
        String mediationRit = adRecordVo.getArMediationRit();
        if (StrUtil.isNotEmpty(mediationRit)) {
            entityWrapper.eq("ar_mediation_rit", mediationRit);
        }
        Integer plUserId = getUser().getPlUserId();
        if (ObjectUtil.isNotNull(plUserId)) {
            String usId = adRecordVo.getUsId();
            List<Integer> userIdList = iFriendService.getUserIdList(plUserId, StrUtil.isNotEmpty(usId) ? Integer.parseInt(usId) : null);
            if (ObjectUtil.isNull(userIdList)) {
                entityWrapper.eq("us_id", -1);
            } else {
                entityWrapper.in("us_id", userIdList);
            }
        } else {
            String usId = adRecordVo.getUsId();
            if (StrUtil.isNotEmpty(usId)) {
                entityWrapper.eq("us_id", usId);
            }
            String usParentId = adRecordVo.getUsParentId();
            if (StrUtil.isNotEmpty(usParentId)) {
                entityWrapper.eq("us_parent_id", usParentId);
            }
        }
        String nickname = adRecordVo.getUsNickname();
        if (StrUtil.isNotEmpty(nickname)) {
            entityWrapper.like("us_nickname", nickname, SqlLike.RIGHT);
        }
        String arCallback = adRecordVo.getArCallback();
        if (StrUtil.isNotEmpty(arCallback)) {
            entityWrapper.eq("ar_callback", arCallback);
        }
        String startGoldCoin = adRecordVo.getStartGoldCoin();
        String endGoldCoin = adRecordVo.getEndGoldCoin();
        if (StrUtil.isNotEmpty(startGoldCoin) && StrUtil.isNotEmpty(endGoldCoin)) {
            entityWrapper.between("ar_reality_money", startGoldCoin, Integer.parseInt(endGoldCoin) + 1);
        }
        if (StrUtil.isNotEmpty(startGoldCoin)) {
            entityWrapper.ge("ar_reality_money", startGoldCoin);
        }
        if (StrUtil.isNotEmpty(endGoldCoin)) {
            entityWrapper.le("ar_reality_money", endGoldCoin);
        }
        entityWrapper.orderBy("create_time", false);
        return entityWrapper;
    }
}
